﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace FQY.Infrastructure.Core
{
    public class HttpHelper
    {
        #region Url加密解析
        /// <summary>
        /// Url解码
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string UrlDecode(string str)
        {
            return HttpUtility.UrlDecode(str);
        }

        /// <summary>
        /// URL编码
        /// </summary>
        /// <param name=""></param>
        /// <returns></returns>
        public static string UrlEncode(string str)
        {
            return HttpUtility.UrlEncode(str);
        }
        #endregion


        #region POST
        /// <summary>
        /// POST请求
        /// </summary>
        /// <param name="strFromUrl">请求URL</param>
        /// <param name="strFromData">提交的参数</param>
        /// <returns></returns>
        public static string HttpPost(string strFromUrl, string strFromData, Encoding encoding)
        {
            string formUrl = strFromUrl;
            string formData = strFromData;

            //提交的编码
            byte[] postData = encoding.GetBytes(formData);

            // 设置提交的相关参数 
            HttpWebRequest request = WebRequest.Create(formUrl) as HttpWebRequest;
            request.Method = "POST";
            request.KeepAlive = false;
            request.AllowAutoRedirect = true;
            request.ContentType = "application/x-www-form-urlencoded";
            request.Headers.Add("accept-encoding", "gzip");
            //request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR  3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)";
            request.ContentLength = postData.Length;


            // 提交请求数据 
            System.IO.Stream outputStream = request.GetRequestStream();
            outputStream.Write(postData, 0, postData.Length);
            outputStream.Close();

            HttpWebResponse response;
            Stream responseStream;
            StreamReader reader;
            string strResult = string.Empty;
            response = request.GetResponse() as HttpWebResponse;
            using (responseStream = response.GetResponseStream())
            {
                using (reader = new System.IO.StreamReader(responseStream, encoding))
                {
                    strResult = reader.ReadToEnd();//返回值赋值          
                }
            }
            return strResult;
        }

        public static string HttpPostByJsonParam(string strFromUrl, string strJsonData, Encoding encoding)
        {

            //创建一个HTTP请求  
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(strFromUrl);
            request.ContentType = "application/json;charset=UTF-8";
            request.Accept = "application/json, text/plain";
            request.Method = "POST";
            request.Headers.Add("accept-encoding", "gzip");
            using (var streamWriter = new StreamWriter(request.GetRequestStream()))
            {
                streamWriter.Write(strJsonData);
                streamWriter.Flush();
                streamWriter.Close();
            }
            string strResult = string.Empty;
            var httpResponse = (HttpWebResponse)request.GetResponse();
            using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
            {
                strResult = streamReader.ReadToEnd();
            }
            return strResult;


        }

        /// <summary>
        /// C# post提交并反馈结果
        /// </summary>
        /// <param name="url"></param>
        /// <param name="xmlString"></param>
        /// <returns></returns>
        public static string HttpPostResponse(string url, string jsonData)
        {
            HttpContent httpContent = new StringContent(jsonData, Encoding.UTF8, "application/json");
 
            HttpClient httpClient = new HttpClient();
            HttpResponseMessage res = httpClient.PostAsync(url, httpContent).Result;
            if (res.IsSuccessStatusCode)
            {
                Task<string> t = res.Content.ReadAsStringAsync();
                return t.Result;
            }
            else
            {
                throw new ApplicationException(res.ReasonPhrase);
            }
        }

        #endregion


        #region GET
        /// <summary>
        /// Get请求
        /// </summary>
        /// <param name="_url"></param>
        /// <param name="_encoding"></param>
        /// <returns></returns>
        public static string HttpGet(string strUrl, Encoding encoding)
        {
            WebClient wc = new WebClient();
            if (encoding != null)
            {
                wc.Encoding = encoding;
            }
            return wc.DownloadString(strUrl);
        }
        public static byte[] HttpGetToData(string strUrl, Encoding encoding)
        {
            WebClient wc = new WebClient();
            if (encoding != null)
            {
                wc.Encoding = encoding;
            }
            return wc.DownloadData(strUrl);
        }
        /// <summary>
        /// Get请求数据
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string HttpGetResponse(string url)
        {
            HttpClient httpClient = new HttpClient();
            HttpResponseMessage res = httpClient.GetAsync(url).Result;
            if (res.IsSuccessStatusCode)
            {
                Task<string> t = res.Content.ReadAsStringAsync();
                return t.Result;
            }
            return string.Empty;
        }
        #endregion


        #region PUT
        public static string HttpPut(string strFromUrl, string strFromData, Encoding encoding)
        {
            string formUrl = strFromUrl;
            string formData = strFromData;

            //提交的编码
            byte[] postData = encoding.GetBytes(formData);

            // 设置提交的相关参数 
            HttpWebRequest request = WebRequest.Create(formUrl) as HttpWebRequest;
            Encoding myEncoding = encoding;
            request.Method = "PUT";
            request.KeepAlive = false;
            request.AllowAutoRedirect = true;
            request.ContentType = "application/x-www-form-urlencoded";
            //request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR  3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)";
            request.ContentLength = postData.Length;


            // 提交请求数据 
            System.IO.Stream outputStream = request.GetRequestStream();
            outputStream.Write(postData, 0, postData.Length);
            outputStream.Close();

            HttpWebResponse response;
            Stream responseStream;
            StreamReader reader;
            string strResult = string.Empty;
            response = request.GetResponse() as HttpWebResponse;
            using (responseStream = response.GetResponseStream())
            {
                using (reader = new System.IO.StreamReader(responseStream, encoding))
                {
                    strResult = reader.ReadToEnd();//返回值赋值          
                }
            }
            return strResult;
        }

        /// <summary>
        /// PUT请求
        /// </summary>
        /// <param name="strFromUrl">请求URL</param>
        /// <param name="strFromData">提交的参数</param>
        /// <returns></returns>
        public static string HttpPut2(string strFromUrl, string strFromData, Encoding encoding)
        {
            string formUrl = strFromUrl;
            string formData = strFromData;

            //提交的编码
            byte[] postData = encoding.GetBytes(formData);

            // 设置提交的相关参数 
            HttpWebRequest request = WebRequest.Create(formUrl) as HttpWebRequest;
            request.Method = "PUT";
            request.AllowAutoRedirect = true;
            request.ContentType = "application/json;charset=utf-8;";
            request.ContentLength = postData.Length;


            // 提交请求数据 
            Stream outputStream = request.GetRequestStream();
            outputStream.Write(postData, 0, postData.Length);
            outputStream.Close();

            string a = request.Headers.ToString();


            //获取接口返回值
            string strResult = string.Empty;
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            using (Stream responseStream = response.GetResponseStream())
            {
                using (StreamReader reader = new System.IO.StreamReader(responseStream, encoding))
                {
                    strResult = reader.ReadToEnd();//返回值赋值          
                }
            }
            return strResult;
        }

        #endregion


        public enum CompressionMethod
        {
            GZip = 1,
            Deflate = 2
        }

        public class CompressedContent : HttpContent
        {
            private readonly HttpContent _originalContent;
            private readonly CompressionMethod _compressionMethod;

            public CompressedContent(HttpContent content, CompressionMethod compressionMethod)
            {
                if (content == null)
                {
                    throw new ArgumentNullException("content");
                }

                _originalContent = content;
                _compressionMethod = compressionMethod;

                foreach (KeyValuePair<string, IEnumerable<string>> header in _originalContent.Headers)
                {
                    Headers.TryAddWithoutValidation(header.Key, header.Value);
                }

                Headers.ContentEncoding.Add(_compressionMethod.ToString().ToLowerInvariant());
            }

            protected override bool TryComputeLength(out long length)
            {
                length = -1;
                return false;
            }

            protected async override Task SerializeToStreamAsync(Stream stream, TransportContext context)
            {
                if (_compressionMethod == CompressionMethod.GZip)
                {
                    using (var gzipStream = new GZipStream(stream, CompressionMode.Compress, leaveOpen: true))
                    {
                        await _originalContent.CopyToAsync(gzipStream);
                    }
                }
                else if (_compressionMethod == CompressionMethod.Deflate)
                {
                    using (var deflateStream = new DeflateStream(stream, CompressionMode.Compress, leaveOpen: true))
                    {
                        await _originalContent.CopyToAsync(deflateStream);
                    }
                }
            }
        }

    }
}